home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Util / conv / Acvt.lha / Acvt 1.07 / sources / cdsk_xfd.cpp < prev    next >
C/C++ Source or Header  |  1999-06-10  |  6KB  |  335 lines

  1. //    This program is free software; you can redistribute it and/or modify
  2. //    it under the terms of the GNU General Public License as published by
  3. //    the Free Software Foundation; either version 2 of the License, or
  4. //    any later version.
  5. //
  6. //    This program is distributed in the hope that it will be useful,
  7. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9. //    GNU General Public License for more details.
  10. //
  11. //    You should have received a copy of the GNU General Public License
  12. //    along with this program; if not, write to the Free Software
  13. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. //
  15.  
  16. #include "cdsk_xfd.h"
  17. #include "autil.h"
  18. #include "cfile.h"
  19.  
  20. CXfd::CXfd() : CDisk()
  21. {
  22.     #ifdef _MEMORY_DUMP_
  23.         printf( "CXfd constructed: %08X\n", this );
  24.     #endif
  25. }
  26.  
  27. CXfd::~CXfd()
  28. {
  29.     #ifdef _MEMORY_DUMP_
  30.         printf( "CXfd destructed: %08X\n", this );
  31.     #endif
  32. }
  33.  
  34. typedef enum
  35. {
  36.     LOAD_OK,
  37.     LOAD_BAD_DD_1,
  38.     LOAD_BAD_DD_2,
  39.     LOAD_BAD_DD_3
  40. } LOAD_VARIANT;
  41.  
  42. BOOL CXfd::Load( char* szFname, BOOL bRepair, BOOL bRepairAuto )
  43. {
  44.     LOAD_VARIANT load_method = LOAD_OK;    
  45.  
  46.     int iFirstSectorsSize = 0x80;
  47.  
  48.     CFile cf;
  49.  
  50.     if ( !cf.Open( szFname ) )
  51.     {
  52.         sprintf( m_szLastError, "XFD: Can't open '%s'", szFname );
  53.         return FALSE;
  54.     }
  55.  
  56.     strcpy( m_szFname, szFname );
  57.  
  58.     LONG lFileLen = cf.GetLength();
  59.  
  60.     int iSecs;
  61.     int iSecSize;
  62.  
  63.     if ( lFileLen % 0x80 )
  64.     {
  65.         sprintf( m_szLastError, "XFD: Strange length!" );
  66.         cf.Close();
  67.         return FALSE;
  68.     }
  69.  
  70.     if ( ( lFileLen / 0x80 ) > 1040 )
  71.     {
  72.         iSecSize = 0x100;
  73.  
  74.         iSecs = ( ( lFileLen - 0x180 ) / 0x100 ) + 3;
  75.     }
  76.     else
  77.     {
  78.         iSecSize = 0x80;
  79.         iSecs = lFileLen / 0x80;
  80.     }
  81.  
  82.     if ( ( ( ( iSecs - 3 ) * iSecSize ) + 0x180 ) != lFileLen )
  83.     {
  84.         sprintf( m_szLastError, "XFD: Format violated: (%08lX != %08X)", lFileLen, iSecs * iSecSize );
  85.         m_iErrorCode = CXFD_FORMAT_VIOLATED;
  86.  
  87.         if ( !bRepair )
  88.         {
  89.             cf.Close();
  90.             return FALSE;
  91.         }
  92.         else
  93.         {
  94.             iSecs = lFileLen / iSecSize;
  95.             BYTE abtBuff[ 0x100 ];
  96.  
  97.             memset( abtBuff, 0, 0x100 );
  98.  
  99.             int iM1zeroes = 3;
  100.             int iM2zeroes = 3;
  101.             int iM3zeroes = 3;
  102.  
  103.             cf.Seek( ( 0x02 - 1 ) * 0x80, SEEK_SET );
  104.             cf.Read( abtBuff, 0x80 );
  105.  
  106.             if ( IsBlockEmpty( abtBuff, 0x80 ) )
  107.                 iM1zeroes--;
  108.  
  109.             cf.Seek( ( 0x04 - 1 ) * 0x80, SEEK_SET );
  110.             cf.Read( abtBuff, 0x80 );
  111.  
  112.             if ( IsBlockEmpty( abtBuff, 0x80 ) )
  113.             {
  114.                 iM1zeroes--;
  115.                 iM2zeroes--;
  116.             }
  117.  
  118.             cf.Seek( ( 0x05 - 1 ) * 0x80, SEEK_SET );
  119.             cf.Read( abtBuff, 0x80 );
  120.  
  121.             if ( IsBlockEmpty( abtBuff, 0x80 ) )
  122.                 iM2zeroes--;
  123.  
  124.             cf.Seek( ( 0x06 - 1 ) * 0x80, SEEK_SET );
  125.             cf.Read( abtBuff, 0x80 );
  126.  
  127.             if ( IsBlockEmpty( abtBuff, 0x80 ) )
  128.             {
  129.                 iM1zeroes--;
  130.                 iM2zeroes--;
  131.             }
  132.  
  133.             cf.Seek( -0x180, SEEK_END );
  134.             cf.Read( abtBuff, 0x80 );
  135.             if ( IsBlockEmpty( abtBuff, 0x80 ) )
  136.                 iM3zeroes--;
  137.  
  138.             cf.Read( abtBuff, 0x80 );
  139.             if ( IsBlockEmpty( abtBuff, 0x80 ) )
  140.                 iM3zeroes--;
  141.  
  142.             cf.Read( abtBuff, 0x80 );
  143.             if ( IsBlockEmpty( abtBuff, 0x80 ) )
  144.                 iM3zeroes--;
  145.  
  146.             if ( !iM1zeroes )
  147.             {
  148.                 load_method = LOAD_BAD_DD_1;
  149.             }
  150.             else if ( !iM2zeroes )
  151.             {
  152.                 load_method = LOAD_BAD_DD_2;
  153.             }
  154.             else if ( !iM3zeroes )
  155.             {
  156.                 load_method = LOAD_BAD_DD_3;
  157.             }
  158.  
  159.             if ( !bRepairAuto )
  160.             {
  161.                 printf( "Invalid DD ATR file encountered.\n" );
  162.                 printf( "Choose repair method:\n" );
  163.                 printf( "1) Sector, gap, sector, gap, sector, gap, data\n" );
  164.                 printf( "2) Three sectors, three empty sectors, data\n" );
  165.                 printf( "3) Data, three empty sectors\n" );
  166.                 printf( "4) Don't repair\n" );
  167.  
  168.                 switch( load_method )
  169.                 {
  170.                     case LOAD_BAD_DD_1:
  171.                         printf( "(Method 1 looks best)\n" );
  172.                         break;
  173.  
  174.                     case LOAD_BAD_DD_2:
  175.                         printf( "(Method 2 looks best)\n" );
  176.                         break;
  177.  
  178.                     case LOAD_BAD_DD_3:
  179.                         printf( "(Method 3 looks best)\n" );
  180.                         break;
  181.  
  182.                     default:
  183.                         break;
  184.                 }
  185.  
  186.                 int iMethod;
  187.  
  188.                 printf( "\n" );
  189.                 do
  190.                 {
  191.                     iMethod = getch() - '0';
  192.                 } while( ( iMethod < 1 ) || ( iMethod > 4 ) );
  193.  
  194.                 if ( iMethod == 4 )
  195.                 {
  196.                     cf.Close();
  197.                     return FALSE;
  198.                 }
  199.             }
  200.             else
  201.             {
  202.                 if ( load_method == LOAD_OK )
  203.                     load_method = LOAD_BAD_DD_1;
  204.             }
  205.  
  206.             cf.Seek( 0, SEEK_SET );
  207.  
  208.             switch( load_method )
  209.             {
  210.                 case LOAD_BAD_DD_1:
  211.                 case LOAD_BAD_DD_2:
  212.                     iFirstSectorsSize = 0x100;
  213.                     break;
  214.  
  215.                 default:
  216.                     break;
  217.                     
  218.             }
  219.                     
  220.         
  221.         }
  222.     }
  223.  
  224.     DISK_GEOMETRY dg;
  225.  
  226.     GuessClassicSizes( iSecs, iSecSize, &dg );
  227.  
  228.     if ( !Format( &dg ) )
  229.     {
  230.         cf.Close();
  231.         return FALSE;
  232.     }
  233.  
  234.     BYTE abtBuff[ 0x100 ];
  235.     memset( abtBuff, 0, 0x100 );
  236.  
  237.     for( int i = 0; i < iSecs; i++ )
  238.     {
  239.         switch( load_method )
  240.         {
  241.             default:
  242.             case LOAD_OK:
  243.                 cf.Read( abtBuff, ( i < 3 ) ? 0x80 : iSecSize );
  244.                 break;
  245.  
  246.             case LOAD_BAD_DD_1:
  247.                 if ( i < 3 )
  248.                 {
  249.                     cf.Read( abtBuff, 0x80 );
  250.                     cf.Seek( 0x80, SEEK_CUR );
  251.                 }
  252.                 else
  253.                     cf.Read( abtBuff, 0x100 );
  254.                 break;
  255.  
  256.             case LOAD_BAD_DD_2:
  257.                 if ( i < 3 )
  258.                 {
  259.                     cf.Read( abtBuff, 0x80 );
  260.  
  261.                     if ( i == 2 )
  262.                         cf.Seek( 0x180, SEEK_CUR );
  263.                 }
  264.                 else
  265.                     cf.Read( abtBuff, 0x100 );
  266.  
  267.                 break;
  268.  
  269.             case LOAD_BAD_DD_3:
  270.                 if ( i < 3 )
  271.                     cf.Read( abtBuff, 0x80 );
  272.                 else
  273.                     cf.Read( abtBuff, 0x100 );
  274.  
  275.                 break;
  276.         }
  277.  
  278.         if ( !WriteSector( i + 1, abtBuff ) )
  279.         {
  280.             cf.Close();
  281.             return FALSE;
  282.         }
  283.     }
  284.  
  285.     cf.Close();
  286.     return TRUE;
  287.  
  288. }
  289.  
  290. #ifdef __CDISK_WRITE__
  291.  
  292. BOOL CXfd::Save( char* szOutFile, BOOL bOverWrite )
  293. {
  294.     CFile cf;
  295.  
  296.     if ( !bOverWrite && !access( szOutFile, F_OK ) )
  297.     {
  298.         sprintf( m_szLastError, "XFD: File already exists! '%s'", szOutFile );
  299.         return FALSE;
  300.     }
  301.  
  302.     if ( !cf.Create( szOutFile ) )
  303.     {
  304.         sprintf( m_szLastError, "XFD: Can't create '%s'", szOutFile );
  305.         return FALSE;
  306.     }
  307.  
  308.     BYTE abtBuff[ 0x100 ];
  309.  
  310.     for( WORD i = 1; i <= m_geometry.iSectors; i++ )
  311.     {
  312.         if ( !ReadSector( abtBuff, i ) )
  313.             return FALSE;
  314.  
  315.         int iToWrite = ( i <= 3 ) ? 0x80: m_geometry.iBytesPerSector;
  316.  
  317.         int iWritten;
  318.  
  319.         if ( !cf.Write( abtBuff, iToWrite, &iWritten ) || ( iWritten != iToWrite ) )
  320.         {
  321.             sprintf( m_szLastError, "XFD: Can't write!" );
  322.             cf.Close();
  323.             unlink( szOutFile );
  324.             return FALSE;
  325.         }
  326.  
  327.     }
  328.  
  329.     cf.Close();
  330.  
  331.     return TRUE;
  332. }
  333.  
  334. #endif //__CDISK_WRITE__
  335.